package com.zoweunion.mechanic.service.order.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zoweunion.mechanic.dao.TSTtOrderMapper;
import com.zoweunion.mechanic.dao.app.AppDao;
import com.zoweunion.mechanic.dao.app.OrderDao;
import com.zoweunion.mechanic.dao.base.UpkeepDao;
import com.zoweunion.mechanic.dao.base.UserDao;
import com.zoweunion.mechanic.dao.order.CGOrderDao;
import com.zoweunion.mechanic.dao.order.KFOrderDao;
import com.zoweunion.mechanic.model.ResponseBean;
import com.zoweunion.mechanic.model.User;
import com.zoweunion.mechanic.service.app.OrderService;
import com.zoweunion.mechanic.service.app.ToolViewBoardService;
import com.zoweunion.mechanic.service.order.CGOrderService;
import com.zoweunion.mechanic.util.*;
import com.zoweunion.mechanic.util.certificate.OperationCertificate;
import com.zoweunion.mechanic.util.certificate.OperationCertificateOrder;
import com.zoweunion.mechanic.util.certificate.OperationCertificateOrderDetail;
import com.zoweunion.mechanic.util.certificate.OrderPay;
import com.zoweunion.mechanic.util.constants.Constants;
import com.zoweunion.mechanic.util.entity.OrderCheck;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.*;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * 仓管工单业务类
 *
 * @author Administrator
 */
@Service
@Transactional
public class CGOrderServiceImpl implements CGOrderService {

    @Autowired
    private TSTtOrderMapper tsTtOrderMapper;
    @Autowired
    private CGOrderDao cGOrderDao;
    @Autowired
    private KFOrderDao kFOrderDao;
    @Autowired
    private AppDao appDao;
    private static Logger logger = LoggerFactory.getLogger(CGOrderEntity.class);
    @Autowired
    private OrderDao orderDao;

    @Autowired
    private UpkeepDao upkeepDao;
    @Autowired
    private OrderService orderService;


    @Autowired
    private UserDao userDao;
    @Autowired
    private ToolViewBoardService toolViewBoardService;

    /**
     * 电商ID
     */
    private final String EBusinessID = "1580543";
    /**
     * 电商加密私钥，快递鸟提供，注意保管，不要泄漏
     */
    private final String AppKey = "366fdb53-0c24-4de7-b7be-9556ee9dd8ca";
    /**
     * 及时查询和单号识别url
     */
    private final String ReqURL = "http://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx";

    @Override
    @Transactional(readOnly = true)
    public Map<String, Object> listByStatus(Map<String, Object> reqMap) {

        // 1.设置分页的limit和offset
        Map<String, Object> pageMap = Page.appPage(reqMap.get("pageSize").toString(),
                reqMap.get("currentPage").toString());
        reqMap.put("pageSize", pageMap.get("limit"));
        reqMap.put("currentPage", pageMap.get("offset"));
        int limit = Integer.valueOf(pageMap.get("limit").toString());
        // 2.查询总记录数
        int total = cGOrderDao.countBycondition(reqMap);

        // 3执行分页查询
        List<Map<String, Object>> orderList = cGOrderDao.listByStatus(reqMap);

        // 4根据工单id关联查询修工列表
		/*if (total > 0) {
			for (Map<String, Object> orderMap : orderList) {
				orderMap.put("order_id", orderMap.get("id"));
				List<Map<String, Object>> repairmanInfo = kFOrderDao.getOrderRepairmanByOrderId(orderMap);
				orderMap.put("repairmanInfo", repairmanInfo);
				List<Map<String, Object>> faultInfo = cGOrderDao.getFaultListByByOrderId(orderMap);
				orderMap.put("faultInfo", faultInfo);
			}
		}*/

        // 4 根据工单id关联查询故障列表
        if (total > 0) {

            orderList.forEach(orderMap -> {
                orderMap.put("order_id", orderMap.get("id"));
                List<Map<String, Object>> byByOrderId = cGOrderDao.getFaultListByByOrderId(orderMap);
                List<Map<String, Object>> mapList = toolViewBoardService.listByFault(byByOrderId, reqMap.get("s_id").toString());
                orderMap.put("faultInfo", mapList);
            });

        }

        // 5根据工单id关联查询修工
        if (total > 0) {
            orderList.forEach(orderMap -> {

                orderMap.put("order_id", orderMap.get("id"));
                orderMap.put("repairmanInfo", kFOrderDao.getOrderRepairmanByOrderId(orderMap));
            });
        }

        if (total > 0) {

            orderList.forEach(orderMap -> {

                // 工单原始的配件
                List<Map<String, Object>> orderPartsOrigin = appDao.findOrderPartsByIdForOrigin(orderMap);
                orderMap.put("order_parts_origin", orderPartsOrigin);

                // 工单变化的配件
                List<Map<String, Object>> orderPartsChange = appDao.findOrderPartsByIdForChange(orderMap);
                orderMap.put("order_parts_change", orderPartsChange);
            });
        }

        //查询订单的故障类型
        orderList.forEach(orderMap -> {
            List<String> dictionaries_nameList = kFOrderDao.getDictionariesName(orderMap);

            orderMap.put("dictionaries_nameList", dictionaries_nameList);

        });
        // 5包装结果集 总条数 总页数 数据集
        HashMap<String, Object> resultMap = new HashMap<String, Object>();
        int pages = (total + limit - 1) / limit;// 总页数 需要有余进一
        //获取当前登入用户
        User user = (User) reqMap.get("user");
        //获取当前用户的角色
        String r_id = user.getR_id();
        //将符合地域要求的工单分发给对应的客服
        //判断当前登入用户是否 为修工
        if (r_id.equals(Constants.ROLE_XG)) {
            //获取当前修工所擅长的故障类型
            String speciality = user.getSpeciality() == null ? "" : user.getSpeciality();
            //当前修工所负责的区域
            String area = user.getArea() == null ? "" : user.getArea();
            List<Map<String, Object>> resultList = orderList.stream()
                    .filter(map -> {
                        if (map.get("area") == null) {
                            return true;
                        }
                        //判断该工单所在的地域属于哪一类省份(按省,自治区,直辖市分类)
                        if (map.get("area").toString().contains("省")) {
                            int index = map.get("area").toString().indexOf("省");
                            //截取该工单所对应的省份
                            String province = map.get("area").toString().substring(0, index + 1);
                            //查看该工单所对应的大区
                            String region_name = kFOrderDao.getRegionByProvince(province);
                            //获取工单的故障类型列表
                            @SuppressWarnings("unchecked")
                            List<String> dictionaries_nameList = JSONObject.parseObject(map.get("dictionaries_nameList").toString(), List.class);
                            //判断当前工单的故障类型是否属于修工的特长之一
                            Boolean flag = dictionaries_nameList.stream().anyMatch(x -> {
                                return speciality.contains(x);
                            });
                            //若修工所服务的地域包含该工单所在的省份,则返回true,否则返回false,此处需注意返回的工单信息必须包含故障类型,否则报空指针异常.
                            if (area.contains(region_name) && flag) {
                                return true;
                            } else {
                                return false;
                            }
                        } else if (map.get("area").toString().contains("区")) {
                            int index = map.get("area").toString().indexOf("区");
                            String province = map.get("area").toString().substring(0, index + 1);
                            String region_name = kFOrderDao.getRegionByProvince(province);
                            @SuppressWarnings("unchecked")
                            List<String> dictionaries_nameList = JSONObject.parseObject(map.get("dictionaries_nameList").toString(), List.class);
                            //判断当前工单的故障类型是否属于修工的特长之一
                            Boolean flag = dictionaries_nameList.stream().anyMatch(x -> {
                                return speciality.contains(x);
                            });
                            if (area.contains(region_name) && flag) {
                                return true;
                            } else {
                                return false;
                            }
                        } else {
                            int index = map.get("area").toString().indexOf("市");
                            String province = map.get("area").toString().substring(0, index + 1);
                            String region_name = kFOrderDao.getRegionByProvince(province);
                            @SuppressWarnings("unchecked")
                            List<String> dictionaries_nameList = JSONObject.parseObject(map.get("dictionaries_nameList").toString(), List.class);
                            //判断当前工单的故障类型是否属于修工的特长之一
                            Boolean flag = dictionaries_nameList.stream().anyMatch(x -> {
                                return speciality.contains(x);
                            });
                            if (area.contains(region_name) && flag) {
                                return true;
                            } else {
                                return false;
                            }
                        }
                    }).collect(Collectors.toCollection(ArrayList::new));
            resultMap.put("total", total);
            resultMap.put("pages", pages);
            resultMap.put("list", resultList);

        } else {
            resultMap.put("total", total);
            resultMap.put("pages", pages);
            resultMap.put("list", orderList);
        }
        return resultMap;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> getOrderInfo(Map<String, Object> reqMap) {
        String userId = reqMap.get("user_id").toString();
        // 1.根据工单id获取总工单信息
        Map<String, Object> orderMap = kFOrderDao.getOrderInfoByOrderId(reqMap);
        //更新仓管响应时间
        if (Integer.valueOf(orderMap.get("order_status").toString())==5){
            OrderCheck checkByOrderId = orderService.selectCheckByOrderId(orderMap.get("id").toString(),
                    userId,Constants.ORDER_CHECK_CG_RESPONSE);
            if (checkByOrderId!=null&&checkByOrderId.getEndTime()==null){
                if(orderService.isCheckTypeExist(checkByOrderId.getOrderId(),checkByOrderId.getUserId(),Constants.ORDER_CHECK_CG_PASTS_RESPONSE) == 0)
                {
                    orderService.updateKfEndTimeList(checkByOrderId.getId());
                    //插入仓管准备配件数据
                    orderService.insertTzOrderCheck(OrderCheck.builder()
                            .orderId(checkByOrderId.getOrderId())
                            .orderNo(checkByOrderId.getOrderNo())
                            .userId(checkByOrderId.getUserId())
                            .roleType(Constants.ROLE_CG)
                            .orderCreateTime(checkByOrderId.getOrderCreateTime())
                            .checkType(Constants.ORDER_CHECK_CG_PASTS_RESPONSE)
                            .build());
                }

            }

        }

        // 2.根据order_id 获取关联修工信息
        List<Map<String, Object>> orderRepairmanList = kFOrderDao.getOrderRepairmanByOrderId(reqMap);
        orderMap.put("repairmanInfo", orderRepairmanList);// repairman_id repairman_name repairman_type check_status
        // check_time

        // 3获取原始列表 维修列表
        reqMap.put("change_flags", new int[]{0});
        reqMap.put("p_type", 1);
        List<Map<String, Object>> orderParts = kFOrderDao.getPartsByCondition(reqMap);
        // 3获取原始列表
        reqMap.put("change_flags", new int[]{0});
        reqMap.put("p_type", 2);
        List<Map<String, Object>> upkeeperParts = kFOrderDao.getPartsByCondition(reqMap);

        reqMap.remove("p_type");

        // 4获取新增的配件
        reqMap.put("change_flags", new int[]{1});
        List<Map<String, Object>> increaseParts = kFOrderDao.getPartsByCondition(reqMap);
        for (Map<String, Object> map : increaseParts) {
            map.put("quantity", map.get("quantity_change"));
        }
        orderMap.put("increaseParts", increaseParts);

        // 4获取返仓(减少)的配件
        reqMap.put("change_flags", new int[]{2});
        List<Map<String, Object>> decreaseParts = kFOrderDao.getPartsByCondition(reqMap);
        for (Map<String, Object> map : decreaseParts) {
            map.put("quantity", map.get("quantity_change"));
        }

        orderMap.put("orderParts", orderParts);//orderPartsOldList
        orderMap.put("upkeeperParts", upkeeperParts);
        orderMap.put("decreaseParts", decreaseParts);

        // 5查询是否包含父级工单
        if ("4".equals(orderMap.get("order_type").toString())) {
            if (null != orderMap.get("parent_id")) {
                String orderType = kFOrderDao.getOrderTupeByOrderId(orderMap.get("parent_id").toString());
                orderMap.put("parent_order_type", Integer.parseInt(orderType));
            }
            return orderMap;
        } else {

            return orderMap;
        }
    }

    @Override
    public int doNoEnough(Map<String, Object> reqMap) {

        return cGOrderDao.doNoEnough(reqMap);

    }

    @Override
    public int insertParts(Map<String, Object> upkeepPartsMap, String order_id, String uuid, int type,
                           String current_user_id) {
        upkeepPartsMap.put("order_id", order_id);
        upkeepPartsMap.put("id", uuid);
        upkeepPartsMap.put("p_type", type);
        upkeepPartsMap.put("current_user_id", current_user_id);
        return cGOrderDao.insertParts(upkeepPartsMap);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertzjParts(Map<String, Object> reqMap) {

        // 表里存储的配件
        List<Map<String, Object>> savePartsList = cGOrderDao.getSavePartsList(reqMap);
        List<CGOrderEntity> insertParts = new ArrayList<CGOrderEntity>();
        List<Map<String, Object>> deleteParts = new ArrayList<>();
        //修改
        List<String> p_idList = new ArrayList<>();

        // 第二次返修新增配件的费用
        double returnRepairPayAmount =0.0;

        //此处维修保养合并 p_type=1维修/2保养
        List<CGOrderEntity> repairParts = JSONObject.parseArray(reqMap.get("repairParts").toString(), CGOrderEntity.class);
        repairParts.parallelStream().forEach(item -> {
            item.setOrder_id(reqMap.get("order_id").toString());
            item.setS_id(reqMap.get("s_id").toString());
            item.setCurrent_user_id(reqMap.get("current_user_id").toString());
            if (item.getId() == null || item.getId().isEmpty()) {
                // 通过 sid name code 判断唯一配件
                if (cGOrderDao.selectParts(item) == 0) {
                    //新增配件
                    String uuid = UuidUtil.get32UUID();
                    item.setParts_id(uuid);
                    cGOrderDao.insertTParts(item);
                }
            } else {
                item.setParts_id(item.getId());
            }
            //判断名称 单位 价格不为空
            if ((item.getDictionaries_unit() == null || item.getDictionaries_unit().isEmpty()) &&
                    (item.getDictionaries_name() == null || item.getDictionaries_name().isEmpty()) &&
                    (item.getPrice() == null || item.getPrice().isEmpty())) {
                try {
                    throw new MyException(Constants.CODE_HANDEL_FAILED, "配件名称，单位或者价格为空，前检查导入的配件");
                } catch (MyException e) {
                    e.printStackTrace();
                }
            }
            if (item.getP_id() != null) {
                String p_id = item.getP_id();
                p_idList.add(p_id);
            } else {
                String uuid = UuidUtil.get32UUID();
                item.setId(uuid);
                item.setC_handle_flag(1);
                item.setP_id(uuid);
                cGOrderDao.insertOrderParts(item);
            }
        });

        // 计算新增配件的总价
        if(repairParts.size()>0){
            for (CGOrderEntity item:repairParts){
                if(item.getReturn_repair()!= null){
                    if(item.getReturn_repair().equals(2)){
                        double itemPrice = Double.parseDouble(item.getPrice());
                        double itemNum = Double.parseDouble(item.getQuantity().toString());
                        returnRepairPayAmount = itemNum*itemPrice;
                    }
                }
            }
        }

        // 这里需要计算下订单中的付款金额，return_repair=2的总金额
        if(returnRepairPayAmount>0){
            UpdateWrapper updateWrapper = new UpdateWrapper();
            updateWrapper.eq("id",reqMap.get("order_id"));
            updateWrapper.set("return_repair_pay_amount",returnRepairPayAmount);
            tsTtOrderMapper.update(null,updateWrapper);
        }


        // 删除之前的仓库配件
        for (Map<String, Object> savePart : savePartsList) {
            String saveP_id = savePart.get("p_id").toString();
            if (!p_idList.contains(saveP_id)) {
                savePart.put("order_id", reqMap.get("order_id"));
                savePart.put("s_id", reqMap.get("s_id"));
                savePart.put("current_user_id", reqMap.get("current_user_id"));
                deleteParts.add(savePart);
            }
        }
        if (deleteParts.size() > 0) {
            for (Map<String, Object> part : deleteParts) {
                cGOrderDao.deleteParts(part);
            }
        }
        cGOrderDao.updatePartsList(reqMap);
        return 1;
    }

    @Override
    public int insertjsParts(Map<String, Object> jianshaoPartsMap, String order_id, String uuid, int type,
                             String current_user_id) {
        jianshaoPartsMap.put("order_id", order_id);
        jianshaoPartsMap.put("id", uuid);
        jianshaoPartsMap.put("p_type", type);
        jianshaoPartsMap.put("current_user_id", current_user_id);
        return cGOrderDao.insertjsParts(jianshaoPartsMap);
    }

    @Override
    public int insertxzParts(Map<String, Object> xinzengPartsMap, String order_id, String uuid, int type,
                             String current_user_id) {
        xinzengPartsMap.put("order_id", order_id);
        xinzengPartsMap.put("id", uuid);
        xinzengPartsMap.put("p_type", type);
        xinzengPartsMap.put("current_user_id", current_user_id);
        return cGOrderDao.insertxzParts(xinzengPartsMap);
    }

    @Override
    public int updateOrderStatus(Map<String, Object> reqMap) {

        return cGOrderDao.updateOrderStatus(reqMap);
    }

    @Override
    public int insertOrderDetail(String order_id, String uuid, String handle_user) {

        Map<String, Object> reqMap = new HashMap<>();

        reqMap.put("id", handle_user);
        reqMap.put("order_status", "6");
        reqMap.put("order_id", order_id);

        cGOrderDao.updateOrderDetail(reqMap);

        // 更新工单超时推送
        reqMap.put("user_id", reqMap.get("id"));
        appDao.updateOrderTimeoutPush(reqMap);

        return cGOrderDao.insertOrderDetail(order_id, uuid, handle_user);
    }

    @Override
    public void refreshParts() {
        //todo 按照时间转换为天当成循环条件
        List<Integer> integers = cGOrderDao.selectPartsByTime();
        integers.stream().forEach(item -> {
            //时间
            List<CGOrderEntity> orderEntities = cGOrderDao.selectPartsBySId(item);
            this.orderParts(orderEntities, item);

        });
    }

    @Override
    public void countParts() {
        List<CGOrderEntity> orderEntities = cGOrderDao.selectOrderPartsByTime();
        try {
            this.orderParts(orderEntities);
        } catch (Exception e) {
            logger.info("定时统计配件异常");
        }
    }

    @Override
    public PageInfo selectPartsCount(Map<String, Object> map) {
        Integer pageSize = Integer.valueOf(map.get("pageSize").toString());
        Integer currentPage = Integer.valueOf(map.get("currentPage").toString());
        PageHelper.startPage(currentPage, pageSize);
        List<CGOrderEntity> orderEntities = cGOrderDao.selectPartsCount();
        return new PageInfo<CGOrderEntity>(orderEntities);

    }


    private void orderParts(List<CGOrderEntity> orderEntities, Integer item) {
        //pid,sid
        orderEntities.parallelStream().forEach(item1 -> {
            List<CGOrderEntity> orderEntities1 =
                    cGOrderDao.selectPartsByPId(item1.getParts_id(), item1.getS_id(), item);
            //加
            List<CGOrderEntity> entities =
                    orderEntities1.stream().filter(a -> (a.getChange_flag() == 0 || a.getChange_flag() == 1))
                            .collect(Collectors.toList());
            int sum = entities.stream().mapToInt(CGOrderEntity::getQuantity).sum();
            //减
            List<CGOrderEntity> entitiess =
                    orderEntities1.stream().filter(a -> a.getChange_flag() == 2).collect(Collectors.toList());
            int sum1 = entitiess.stream().mapToInt(CGOrderEntity::getQuantity).sum();
            int i = sum - sum1;
            if (i > 1) {
                cGOrderDao.insertPartsCount(PartCountEntity.builder()
                        .count(i)
                        .s_id(item1.getS_id())
                        .create_time(item1.getCreate_time())
                        .parts_id(item1.getParts_id())
                        .build());
            }
        });
    }

    private void orderParts(List<CGOrderEntity> orderEntities) {
        //pid,sid

        orderEntities.parallelStream().forEach(item1 -> {
            List<CGOrderEntity> orderEntities1 =
                    cGOrderDao.selectPartsByPIds(item1.getParts_id(), item1.getS_id());
            //加
            List<CGOrderEntity> entities =
                    orderEntities1.stream().filter(a -> (a.getChange_flag() == 0 || a.getChange_flag() == 1))
                            .collect(Collectors.toList());
            int sum = entities.stream().mapToInt(CGOrderEntity::getQuantity).sum();
            //减
            List<CGOrderEntity> entitiess =
                    orderEntities1.stream().filter(a -> a.getChange_flag() == 2).collect(Collectors.toList());
            int sum1 = entitiess.stream().mapToInt(CGOrderEntity::getQuantity).sum();
            int i = sum - sum1;
            if (i > 1) {
                cGOrderDao.insertPartsCount(PartCountEntity.builder()
                        .count(i)
                        .s_id(item1.getS_id())
                        .create_time(item1.getCreate_time())
                        .parts_id(item1.getParts_id())
                        .build());
            }
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void orderException() {
        List<OrderCount> counts = cGOrderDao.orderException();
        counts.stream().forEach(item -> {
            //插入预约单 完成单
            List<String> selectRepairMan = cGOrderDao.selectRepairMan(item.getOrderId());
            item.setUZxIds(selectRepairMan.size() == 0 ? "" : selectRepairMan.toString());
            cGOrderDao.insertOrderCount(item);
            TimeOutDeploy deploy = cGOrderDao.selectTimeOuTDeploy(TimeOutDeploy.builder()
                    .sId(item.getSId())
                    .build());
            Integer cgTime = 0;
            if (deploy != null) {
                cgTime = deploy.getCgTime();
            }
            //完成单筛选异常单
            if (item.getOrderStatus() == Constants.ORDER_STATUS_DZF) {
                this.insertException(Constants.UserBehaviorEnum.ExceptionStatus.REPAIRARRIVE.getStatus(),
                        item.getId(), item.getOrderId(), cgTime, item.getAppraiseStatus());
                this.insertException(Constants.UserBehaviorEnum.ExceptionStatus.SUPPORTSTAFF.getStatus(),
                        item.getId(), item.getOrderId(), cgTime, item.getAppraiseStatus());
                this.insertException(Constants.UserBehaviorEnum.ExceptionStatus.REPAIR.getStatus(),
                        item.getId(), item.getOrderId(), cgTime, item.getAppraiseStatus());
                this.insertException(Constants.UserBehaviorEnum.ExceptionStatus.PARTSEXACT.getStatus(),
                        item.getId(), item.getOrderId(), cgTime, item.getAppraiseStatus());
                this.insertException(Constants.UserBehaviorEnum.ExceptionStatus.WAREHOUSERESPONSE.getStatus(),
                        item.getId(), item.getOrderId(), cgTime, item.getAppraiseStatus());
            }
        });
    }

    @Override
    public OrderException selectOrderCountHead(Map<String, Object> map) throws ParseException {
        Date startTime = Orgin.getDate(map, "startTime");
        Date endTime = Orgin.getDate(map, "endTime");
        String s_id = Orgin.getString(map, "s_id");
        OrderException orderException = new OrderException();
        //查询销售额,完成/预约工单
        List<OrderCount> counts = cGOrderDao.selectOrderCount(startTime, endTime, s_id);
        if (counts.size() == 0) {
            return orderException;
        }
        orderException.setYyOrder(0);
        orderException.setWcOrder(0);
        counts.forEach(item -> {
            if (item.getOrderStatus() == 15) {
                orderException.setWcOrder(item.getCountSum().intValue());
            } else if (item.getOrderStatus() == 2) {
                orderException.setYyOrder(item.getCountSum().intValue());
            }
        });
        Integer countSum = orderException.getWcOrder().intValue();
        //todo 销售总额
        if (countSum != 0) {
            String aDouble = cGOrderDao.selectOrderPriceCount(startTime, endTime, s_id);
            Double d = Double.parseDouble(aDouble);
            DecimalFormat df = new DecimalFormat("0.00");
            String s = df.format(d);
            orderException.setPrice(s);
        }

        //正常工单比
        List<Map<String, Object>> list = cGOrderDao.selectOrderCountNormal(startTime, endTime, s_id);
        if (countSum == 0) {
            orderException.setZcTotal("0%");
        } else {
            orderException.setZcTotal(mapTotal(countSum, list.size()));
        }

        List<OrderException> exceptions = cGOrderDao.selectOrderCountHead(startTime, endTime, s_id);
        exceptions.stream().forEach(item -> {
            switch (item.getExceptionStatus()) {
                case 1:
                    orderException.setXgZsException(item.getCountSum());
                    orderException.setXgZsPercent(mapTotal(countSum, item.getCountSum().intValue()));
                    break;
                case 2:
                    orderException.setKfException(item.getCountSum());
                    orderException.setKfPercent(mapTotal(countSum, item.getCountSum().intValue()));
                    break;
                case 3:
                    orderException.setXgFxException(item.getCountSum());
                    orderException.setXgOFxPercent(mapTotal(countSum, item.getCountSum().intValue()));
                    orderException.setXgFxPercent(mapFxTotal(countSum, item.getCountSum().intValue()));
                    break;
                case 4:
                    orderException.setTzException(item.getCountSum());
                    orderException.setTzPercent(mapTotal(countSum, item.getCountSum().intValue()));
                    break;
                case 5:
                    orderException.setCgException(item.getCountSum());
                    orderException.setCgPercent(mapTotal(countSum, item.getCountSum().intValue()));
                    break;
            }
        });
        if (exceptions.stream().noneMatch(item -> item.getExceptionStatus() == 1) && countSum != 0) {
            orderException.setXgZsPercent("100%");
        }
        if (exceptions.stream().noneMatch(item -> item.getExceptionStatus() == 2) && countSum != 0) {
            orderException.setKfPercent("100%");
        }
        if (exceptions.stream().noneMatch(item -> item.getExceptionStatus() == 3) && countSum != 0) {
            orderException.setXgOFxPercent("100%");
        }
        if (exceptions.stream().noneMatch(item -> item.getExceptionStatus() == 4) && countSum != 0) {
            orderException.setTzPercent("100%");
        }
        if (exceptions.stream().noneMatch(item -> item.getExceptionStatus() == 5) && countSum != 0) {
            orderException.setCgPercent("100%");
        }
        return orderException;
    }

    @Override
    public PageInfo selectOrderByException(Map<String, Object> map) throws ParseException {
        String startTime = map.get("startTime").toString();
        String endTime = map.get("endTime").toString();
        String s_id = map.get("s_id").toString();
        String u_id = map.get("u_id").toString();
        Integer status = 0;
        if (!map.get("status").equals("")) {
            status = Integer.valueOf(map.get("status").toString());
        }
        Integer pageSize = Integer.valueOf(map.get("pageSize").toString());
        Integer currentPage = Integer.valueOf(map.get("currentPage").toString());
        PageHelper.startPage(currentPage, pageSize);
        List<Map<String, Object>> mapList = cGOrderDao.selectOrderByException(stringConvertDate(startTime), stringConvertDate(endTime)
                , s_id, u_id, status);
        this.OrderDetails(map, mapList);
        PageInfo<Map<String, Object>> mapPageInfo = new PageInfo<>(mapList);
        return mapPageInfo;
    }

    @Override
    public PageInfo selectOrderByTime(Map<String, Object> map) throws ParseException {
        String startTime = map.get("startTime").toString();
        String endTime = map.get("endTime").toString();
        String s_id = map.get("s_id").toString();
        String u_id = map.get("u_id").toString();
        Integer status = 0;
        if (!map.get("status").equals("")) {
            status = Integer.valueOf(map.get("status").toString());
        }
        Integer pageSize = Integer.valueOf(map.get("pageSize").toString());
        Integer currentPage = Integer.valueOf(map.get("currentPage").toString());
        PageHelper.startPage(currentPage, pageSize);
        List<Map<String, Object>> orderList = cGOrderDao.selectOrderByTime(stringConvertDate(startTime)
                , stringConvertDate(endTime), s_id, u_id,status);


        this.OrderDetails(map, orderList);


        PageInfo<Map<String, Object>> mapPageInfo = new PageInfo<>(orderList);
        return mapPageInfo;
    }

    @Override
    public Map<String, Object> selectPercentByUser(Map<String, Object> map) throws ParseException {
        String startTime = map.get("startTime").toString();
        String endTime = map.get("endTime").toString();
        String s_id = map.get("s_id").toString();
        Map<String, Object> objectHashMap = new HashMap<>();

        List<OrderCount> countss = cGOrderDao.selectOrderCount(stringConvertDate(startTime)
                , stringConvertDate(endTime), s_id);
        if (countss.size() == 0) {
            Map<String, Object> kfList = new HashMap<String, Object>();
            kfList.put("kfList", new String[0]);
            kfList.put("cgList", new String[0]);
            kfList.put("tzList", new String[0]);
            kfList.put("xgList", new String[0]);
            return kfList;
        }
        Integer countSum1 = Integer.valueOf(countss.get(0).getCountSum().toString());//完成
        //客服满意度
        List<OrderException> counts = cGOrderDao.selectOrderCountPerson(stringConvertDate(startTime)
                , stringConvertDate(endTime), s_id);
        objectHashMap.put("kfList", this.countGet(counts, startTime, endTime, s_id));

        //仓管准时
        List<OrderException> cgList = cGOrderDao.selectOrderCountCg(stringConvertDate(startTime)
                , stringConvertDate(endTime), s_id);
        objectHashMap.put("cgList", this.countGetcg(cgList, startTime, endTime, s_id));

        //听诊
        List<OrderException> tzList = cGOrderDao.selectOrderCountTz(stringConvertDate(startTime)
                , stringConvertDate(endTime), s_id);
        objectHashMap.put("tzList", this.countGettz(tzList, startTime, endTime, s_id));

        //修工
        List<OrderCount> orderCounts = cGOrderDao.selectOrderCountXg(stringConvertDate(startTime)
                , stringConvertDate(endTime), s_id);
        List<String> xgList = new ArrayList<String>();
        orderCounts.forEach(item -> {
            if (item.getUZxIds() != "") {
                String stt = item.getUZxIds().replaceAll(" ", "");
                String str[] = stt.substring(1, stt.length() - 1).split(",");
                xgList.addAll(Arrays.asList(str));
            }

        });
        List<OrderException> xgList1 = new ArrayList<>();
        List<String> listAllDistinct = xgList.stream().distinct().collect(Collectors.toList());
        listAllDistinct.forEach(item -> {
            try {
                OrderException exception = cGOrderDao.selectPercentByXgL(stringConvertDate(startTime), stringConvertDate(endTime)
                        , s_id, item);
                exception.setPercent(mapFxTotal(countSum1, exception.getCountSum().intValue()));
                Map<String, Object> byId = userDao.getUserById(item);
                if (byId != null) {
                    exception.setCreateUer(byId.get("user_name").toString());
                    exception.setMobilePhone(byId.get("mobile_phone").toString());
                    exception.setUpdateUser(byId.get("id").toString());
                }
                xgList1.add(exception);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        });
        objectHashMap.put("xgList", xgList1);
        return objectHashMap;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateTimeOuTDeploy(TimeOutDeploy timeOutDeploy) {
        cGOrderDao.updateTimeOuTDeploy(timeOutDeploy);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseBean insertTimeOutLevel(TimeOutLevel timeOutLevel) {
        cGOrderDao.deleteTimeOutLevel(timeOutLevel);
        timeOutLevel.getTimeOutLevelList().forEach(item -> {
            int i = cGOrderDao.selectByLevelUser(item);
            if (i == 0) {
                item.setSid(timeOutLevel.getSid());
                cGOrderDao.insertTimeOutLevel(item);
            }
        });
        return new ResponseBean(Constants.CODE_SUCCESS, "操作成功", "");
    }

    @Override
    public TimeOutDeploy selectTimeOuTDeploy(TimeOutDeploy timeOutLevel) {
        return cGOrderDao.selectTimeOuTDeploy(timeOutLevel);
    }

    @Override
    public List<TimeOutLevel> selectTimeOutLevel(TimeOutLevel timeOutLevel) {

        return cGOrderDao.selectTimeOutLevel(timeOutLevel);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void selectDictionariesBy() {
        //动力系统
        List<String> strings = new ArrayList<String>();
        strings.add("发动机");
        strings.add("散热器");
        strings.add("上、下水管");
        strings.add("副水箱");
        strings.add("空气滤清器");
        strings.add("消声器");
        strings.add("燃油箱");
        strings.add("燃油滤清器");
        strings.add("燃油管");
        strings.add("联轴器");
        strings.add("风扇");
        strings.add("水泵");
        strings.add("柴油泵、油嘴");
        strings.add("风扇皮带");


        //液压系统
        List<String> yyxt = new ArrayList<String>();
        yyxt.add("大泵");
        yyxt.add("整车管路");
        yyxt.add("多路阀");
        yyxt.add("回转马达");
        yyxt.add("液压油箱");
        yyxt.add("回转中央接头");
        yyxt.add("液压管路");
        yyxt.add("先导阀");
        yyxt.add("脚先导阀");
        yyxt.add("推土先导阀");
        yyxt.add("三联电磁阀组");

        //电器系统
        List<String> dqxt = new ArrayList<String>();
        dqxt.add("蓄电池");
        dqxt.add("油门电机");
        dqxt.add("熄火电机");
        dqxt.add("电源开关");
        dqxt.add("整车电路");
        dqxt.add("照明灯");
        dqxt.add("喇叭");
        dqxt.add("空调");
        dqxt.add("压缩机");
        dqxt.add("冷凝器");
        dqxt.add("整车开关");
        dqxt.add("雨刮电机");
        dqxt.add("仪表");
        dqxt.add("蒸发器");

        //工作配置
        List<String> gzpz = new ArrayList<String>();
        gzpz.add("动臂");
        gzpz.add("动臂油缸");
        gzpz.add("斗杆");
        gzpz.add("斗杆油缸");
        gzpz.add("连杆");
        gzpz.add("铲斗");
        gzpz.add("铲斗油缸");
        gzpz.add("斗齿");
        gzpz.add("边齿");
        gzpz.add("销轴");
        gzpz.add("轴套");
        gzpz.add("齿销");
        gzpz.add("回转支撑");
        gzpz.add("推土板");
        gzpz.add("工具架");

        //行走配置
        List<String> xzpz = new ArrayList<String>();
        xzpz.add("行走马达");
        xzpz.add("支重轮");
        xzpz.add("涨紧油缸");
        xzpz.add("托链轮");
        xzpz.add("履带");
        xzpz.add("引导轮");
        xzpz.add("引导轮支架");
        xzpz.add("驱动齿");
        xzpz.add("护链架");
        xzpz.add("单向阀");

        //qt
        List<String> qt = new ArrayList<String>();
        qt.add("驾驶室");
        qt.add("机棚");
        qt.add("行走架");
        qt.add("整车玻璃");
        qt.add("整车门锁");
        qt.add("配重");
        qt.add("底板");


        List<DictionariesFault> dictionariesFaults = cGOrderDao.selectByDic();
        dictionariesFaults.forEach(item -> {
            cGOrderDao.insertDictionariesBy(DictionariesFault.builder()
                    .id(item.getId())
                    .dictionariesName(item.getDictionariesName())
                    .sid(item.getSid())
                    .build());
        });

        List<DictionariesFault> faults = cGOrderDao.selectFault();
        faults.forEach(item -> {
            if (item.getDictionariesName().equals("动力系统")) {
                strings.forEach(item1 -> {
                    cGOrderDao.insertDictionariesByNew(DictionariesFault.builder()
                            .id(UuidUtil.get32UUID())
                            .dictionariesName(item1)
                            .sid(item.getSid())
                            .parentId(item.getId())
                            .build());
                });
            }
            if (item.getDictionariesName().equals("液压系统")) {
                yyxt.forEach(item1 -> {
                    cGOrderDao.insertDictionariesByNew(DictionariesFault.builder()
                            .id(UuidUtil.get32UUID())
                            .dictionariesName(item1)
                            .sid(item.getSid())
                            .parentId(item.getId())
                            .build());
                });
            }
            if (item.getDictionariesName().equals("电器系统")) {
                dqxt.forEach(item1 -> {
                    cGOrderDao.insertDictionariesByNew(DictionariesFault.builder()
                            .id(UuidUtil.get32UUID())
                            .dictionariesName(item1)
                            .sid(item.getSid())
                            .parentId(item.getId())
                            .build());
                });
            }
            if (item.getDictionariesName().equals("工作装置")) {
                gzpz.forEach(item1 -> {
                    cGOrderDao.insertDictionariesByNew(DictionariesFault.builder()
                            .id(UuidUtil.get32UUID())
                            .dictionariesName(item1)
                            .sid(item.getSid())
                            .parentId(item.getId())
                            .build());
                });
            }
            if (item.getDictionariesName().equals("行走装置")) {
                xzpz.forEach(item1 -> {
                    cGOrderDao.insertDictionariesByNew(DictionariesFault.builder()
                            .id(UuidUtil.get32UUID())
                            .dictionariesName(item1)
                            .sid(item.getSid())
                            .parentId(item.getId())
                            .build());
                });
            }
            if (item.getDictionariesName().equals("其       他")) {
                xzpz.forEach(item1 -> {
                    cGOrderDao.insertDictionariesByNew(DictionariesFault.builder()
                            .id(UuidUtil.get32UUID())
                            .dictionariesName(item1)
                            .sid(item.getSid())
                            .parentId(item.getId())
                            .build());
                });
            }
        });


    }

    @Override
    public PageInfo selectDictionariesByList(Map<String, Object> map) {
        String parentId = map.get("parentId").toString();
        String s_id = map.get("s_id").toString();
        Integer pageSize = Integer.valueOf(map.get("pageSize").toString());
        Integer currentPage = Integer.valueOf(map.get("currentPage").toString());
        PageHelper.startPage(currentPage, pageSize);
        List<DictionariesFault> dictionariesFaultList = cGOrderDao.selectDictionariesByList(parentId,
                s_id);
        PageInfo<DictionariesFault> mapPageInfo =
                new PageInfo<DictionariesFault>(dictionariesFaultList);
        return mapPageInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseBean insertDictionaries(DictionariesFault dictionariesFault) {
        int i = cGOrderDao.selectDictionDis(dictionariesFault.getSid(), dictionariesFault.getDictionariesName());
        if (i > 0) {
            return new ResponseBean(Constants.CODE_HANDEL_FAILED, "该故障类型已存在,请重新输入", "");
        }
        if (dictionariesFault.getId() != null) {
            cGOrderDao.updateDictionariesBy(dictionariesFault);
        } else {
            dictionariesFault.setId(UuidUtil.get32UUID());
            cGOrderDao.insertDictionariesByNew(dictionariesFault);
        }
        return new ResponseBean(Constants.CODE_SUCCESS, "操作成功", "");
    }

    @Override
    public void deleteDictionaries(DictionariesFault dictionariesFault) {
        cGOrderDao.deleteDictionaries(dictionariesFault);
    }

    @Override
    public String insertCertificateOrder(OperationCertificateOrder order) {
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMddHHmmss");
        order.setOrderId("C"+sdf1.format(new Date())+(int)
                ((Math.random()*9+1)*100000));
        order.setId(UuidUtil.get32UUID());
        order.setOrderStatus(Constants.ORDER_STATUS_WAIT_PAY);//未付款
        cGOrderDao.insertCertificateOrder(order);
        //插入细节表
        OperationCertificateOrderDetail orderDetail = new OperationCertificateOrderDetail();
        this.insertCertificateOrderDetail(orderDetail,order);
        return order.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteTest() {
        List<Map<String, Object>> selectaa = cGOrderDao.selectaa();
         selectaa.forEach(item -> {
                cGOrderDao.deletedd(Long.valueOf(item.get("id").toString()));
        });


    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseBean insertCertificate(OperationCertificate order) {
        int i = cGOrderDao.selectByCertificateName(order);
        if (i > 0) {
            return new ResponseBean(Constants.CODE_HANDEL_FAILED, "名称重复请重新输入", "");
        } else {
            cGOrderDao.insertCertificate(order);
        }
        return new ResponseBean(Constants.CODE_SUCCESS, "操作成功", "");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteCertificate(OperationCertificate order) {
        cGOrderDao.deleteCertificate(order);
    }

    @Override
    public List<OperationCertificate> selectCertificate(Map<String, Object> map) {
        String operationName = map.get("operationName").toString();
        List<OperationCertificate> certificates = cGOrderDao.selectCertificate(OperationCertificate.builder()
                .parentId(0l)
                .build());
        certificates.forEach(item -> {
            List<OperationCertificate> list = cGOrderDao.selectCertificate(OperationCertificate.builder()
                    .parentId(item.getId())
                    .operationName(operationName)
                    .build());
            item.setCertificateList(list);
        });
        return certificates;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseBean updateCertificate(OperationCertificate order) {
        int i = cGOrderDao.selectByCertificateNameS(order);
        if (i > 0) {
            return new ResponseBean(Constants.CODE_HANDEL_FAILED, "名称重复请重新输入", "");
        } else {
            cGOrderDao.updateCertificate(order);
        }
        return new ResponseBean(Constants.CODE_SUCCESS, "操作成功", order.getId());
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderPay insertCertificateOrderPay(OrderPay order) {
        order.setIsRefund(1);
        order.setOrderType(1);
        cGOrderDao.insertCertificateOrderPay(order);
        Long id = order.getId();
        cGOrderDao.updateCertificateOrder(order.getOrderId(), order.getId());//绑定支付信息
        //插入细节表
        OperationCertificateOrder orderInfo = new OperationCertificateOrder();
        orderInfo.setOrderStatus(2);
        orderInfo.setCreateUser(order.getCreateUser());
        orderInfo.setId(order.getOrderId());
        OperationCertificateOrderDetail orderDetail = new OperationCertificateOrderDetail();
        this.insertCertificateOrderDetail(orderDetail,orderInfo);
        return order;
    }


    @Override
    public OperationCertificateOrder selectCertificateOrderInfo(Map<String, Object> map) {
        String orderId = map.get("id").toString();
        OperationCertificateOrder certificateOrder = cGOrderDao.selectCertificateOrderInfo(orderId);
        List<OperationCertificateOrderDetail> detailList = cGOrderDao.getCertificateDetailList(orderId);
        certificateOrder.setDetailList(detailList);
        this.getProvinceCityName(certificateOrder);
        if (certificateOrder.getExpressNum()!=null&&!certificateOrder.getExpressNum().isEmpty()){
            String expCode = certificateOrder.getExpressNo();//快递公司
            String expNo = certificateOrder.getExpressNum();
            try {
                // 查询物流信息
                String information;
                if ("SF".equals(expCode)) {
                    String customerName = certificateOrder.getPhoneShort().toString();
                    information = this.getOrderTracesByJson(expCode, expNo, customerName);
                } else {
                    information = this.getOrderTracesByJson(expCode, expNo);
                }
                Map<String, Object> informationMap = (Map<String, Object>) JSON.parse(information);
                if (informationMap.containsKey("Reason")) {
                    informationMap.put("message", informationMap.get("Reason").toString());
                }
                informationMap.remove("EBusinessID");
                certificateOrder.setExpress(informationMap);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return certificateOrder;
    }

    private void getProvinceCityName(OperationCertificateOrder certificateOrder) {
        certificateOrder.setProvinceName("");
        certificateOrder.setCityName("");
        certificateOrder.setAreaName("");
        if(certificateOrder.getProvinceNum()!=null){
            Object provinceNameObject = cGOrderDao.getNameByNumber(1,certificateOrder.getProvinceNum()).get("province_name");
            if(provinceNameObject != null){
                certificateOrder.setProvinceName(provinceNameObject.toString());
            }
        }
        if(certificateOrder.getCityNum()!=null){
            Object cityNameObject = cGOrderDao.getNameByNumber(2,certificateOrder.getCityNum()).get("city_name");
            if(cityNameObject != null){
                certificateOrder.setCityName(cityNameObject.toString());
            }
        }
        if(certificateOrder.getAreaNum()!=null){
            Object areaNameObject = cGOrderDao.getNameByNumber(3,certificateOrder.getAreaNum()).get("area_name");
            if(areaNameObject != null){
                certificateOrder.setAreaName(areaNameObject.toString());
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCertificateOrderStatus(OperationCertificateOrder order) {
        cGOrderDao.updateCertificateOrderStatus(order);
        //新增到细节表
        OperationCertificateOrderDetail orderDetail = new OperationCertificateOrderDetail();
        this.insertCertificateOrderDetail(orderDetail,order);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCertificateOrder(OperationCertificateOrder order) {
        cGOrderDao.updateCertificateByOrder(order);
        //插入细节表
        OperationCertificateOrderDetail orderDetail = new OperationCertificateOrderDetail();
        this.insertCertificateOrderDetail(orderDetail,order);
    }

    @Override
    public PageInfo selectCertificateBusiness(Map<String, Object> map) {
        Integer pageSize = Integer.valueOf(map.get("pageSize").toString());
        Integer currentPage = Integer.valueOf(map.get("currentPage").toString());
        PageHelper.startPage(currentPage, pageSize);
        Integer orderStatus = Integer.valueOf(map.get("orderStatus").toString());
        String createUser = map.get("createUser").toString();
        List<OperationCertificateOrder> orderList = cGOrderDao.selectCertificateBusiness(orderStatus, createUser);
        PageInfo<OperationCertificateOrder> mapPageInfo =
                new PageInfo<OperationCertificateOrder>(orderList);
        return mapPageInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteCertificateOrderStatus(OperationCertificateOrder order) {
        cGOrderDao.deleteCertificateOrderStatus(order);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseBean updateCertificateExpress(OperationCertificateOrder order) {
        String expNo = order.getExpressNum();
        Map<String, Object> resultMap=null;
        try {
            String information = this.getOrderTracesTypeByJson(expNo);
            resultMap = JSON.parseObject(information);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (order.getPhoneShort()!=null){
            Map<String, Object> map = new HashMap<>();
            map.put("expNo",order.getExpressNum());
            Map<String, Object> shipperCodeMap = this.judgeInformation(map);
            List<Map<String, Object>> shippers = (List<Map<String, Object>>) shipperCodeMap.get("Shippers");
            if (shippers == null || shippers.size() == 0) {
                return new ResponseBean(Constants.CODE_HANDEL_FAILED, "暂无物流信息，请检查单号是否正确", null);
            }
            order.setExpressNo("SF");
            order.setExpressName("顺丰快递");
        }else {
            List<Map<String, Object>> shippers = (List<Map<String, Object>>)resultMap.get("Shippers");
            if (shippers != null) {
                for (Map<String, Object> shipperMap : shippers) {
                    if (shipperMap.get("ShipperCode") != null) {
                        // 快递公司编码
                        order.setExpressNo(shipperMap.get("ShipperCode").toString());
                        order.setExpressName(shipperMap.get("ShipperName").toString());
                    }
                }
            }
            if (shippers == null || shippers.size() == 0) {
                return new ResponseBean(Constants.CODE_HANDEL_FAILED, "暂无物流信息，请检查单号是否正确", null);
            }
        }
        cGOrderDao.updateCertificateExpress(order);
        return new ResponseBean(Constants.CODE_SUCCESS, "操作成功", order.getId());

    }

    @Override
    public OperationCertificateOrder logisticsExpress(Map<String, Object> reqMap) {
        String id = reqMap.get("id").toString();
        OperationCertificateOrder certificateOrder = cGOrderDao.selectCertificateOrderInfo(id);
        String expCode = certificateOrder.getExpressNo();//快递公司
        String expNo = certificateOrder.getExpressNum();
        try {
            // 查询物流信息
            String information;
            if ("SF".equals(expCode)) {
                String customerName = certificateOrder.getPhoneShort().toString();
                information = this.getOrderTracesByJson(expCode, expNo, customerName);
            } else {
                information = this.getOrderTracesByJson(expCode, expNo);
            }
            Map<String, Object> informationMap = (Map<String, Object>) JSON.parse(information);
            if (informationMap.containsKey("Reason")) {
                informationMap.put("message", informationMap.get("Reason").toString());
            }
            informationMap.remove("EBusinessID");
            certificateOrder.setExpress(informationMap);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return certificateOrder;
    }

    @Override
    public void insertCertificateOrderDetail(OperationCertificateOrderDetail orderDetail,OperationCertificateOrder order) {
        orderDetail.setId(UuidUtil.get32UUID());
        orderDetail.setOrderStatus(order.getOrderStatus());
        orderDetail.setUpdateUser(order.getCreateUser());
        orderDetail.setCreateUser(order.getCreateUser());
        orderDetail.setOrderId(order.getId());
        orderDetail.setDeleteFlag(0);
        int status = orderDetail.getOrderStatus();
        String statusText = null;
        if(status == 1){
            statusText = Constants.ORDER_STATUS_WAIT_PAY_TEXT;//未付款
        }else if(status == 2){
            if(order.getRefuseReason() !=null && !("").equals(order.getRefuseReason())){
                statusText = Constants.ORDER_STATUS_FAIL_AUDIT_TEXT;//审核未通过
            }else{
                statusText = Constants.ORDER_STATUS_WAIT_AUDIT_TEXT;//待审核
                cGOrderDao.removeCertificateFail(order.getId(),Constants.ORDER_STATUS_FAIL_AUDIT_TEXT);//给之前审核失败的记录加上deleteFlag为1
            }
        }else if(status == 3){
            statusText = Constants.ORDER_STATUS_PASS_AUDIT_TEXT;//审核成功
            cGOrderDao.removeCertificateFail(order.getId(),Constants.ORDER_STATUS_FAIL_AUDIT_TEXT);//给之前审核失败的记录加上deleteFlag为1
        }else if(status == 4){
            statusText = Constants.ORDER_STATUS_PASS_TEXT;//待发货
        }else if(status == 5){
            statusText = Constants.ORDER_STATUS_DELIVER_TEXT;//已发货
        }else if(status == 6){
            statusText = Constants.ORDER_STATUS_FINISH_TEXT;//完成
        }
        orderDetail.setId(UuidUtil.get32UUID());
        orderDetail.setStatusText(statusText);
        cGOrderDao.operationCertificateOrderDetail(orderDetail);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateKateWorkHour() {
        List<Map<String, Object>> maps = cGOrderDao.selectKateWorkHour();
        maps.parallelStream().forEach(item->{
            List<Map<String, Object>> selectKateWorkDetail = cGOrderDao.selectKateWorkDetail(item);
            double EngineTotalHours=0d;
            if (selectKateWorkDetail.size()>1){
                EngineTotalHours=Double.valueOf(selectKateWorkDetail.get(0).get("EngineTotalHours").toString())-
                        Double.valueOf((selectKateWorkDetail.get(selectKateWorkDetail.size()-1).get("EngineTotalHours").toString()));
                BigDecimal b = new BigDecimal(EngineTotalHours);
                EngineTotalHours = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            }
            cGOrderDao.updateWorkHour(item.get("things_id").toString(),item.get("sample_date").toString()
                    ,Double.valueOf(EngineTotalHours).toString());
        });
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean insertException(Integer status, Long id, String orderId, Integer deployTime, Integer appriseStatus) {
        Map<String, Object> repairMap = cGOrderDao.selectRepairTime(orderId);
        Map<String, Object> orderAppraise = cGOrderDao.selectOrderAppraise(orderId);
        List<Integer> entities = cGOrderDao.selectOrderTime(orderId);
        switch (status) {
            case 1://todo 修工准时率 实际时间,预计时间
                if (repairMap != null && !repairMap.get("planTime").equals("")) {
                    if (Integer.valueOf(repairMap.get("realTime").toString())
                            > Integer.valueOf(repairMap.get("planTime").toString())) {
                        cGOrderDao.insertException(OrderException.builder()
                                .orderCountId(id)
                                .exceptionStatus(Constants.UserBehaviorEnum.ExceptionStatus.REPAIRARRIVE.getStatus())
                                .build());
                    }
                }
                break;
            case 2://todo 客户满意度 三个字段加起来<9
                if (Double.valueOf(orderAppraise.get("appraise").toString()).intValue() < 9 && appriseStatus == 2) {
                    cGOrderDao.insertException(OrderException.builder()
                            .orderCountId(id)
                            .exceptionStatus(Constants.UserBehaviorEnum.ExceptionStatus.SUPPORTSTAFF.getStatus())
                            .build());
                }
                break;
            case 3://todo 存在parent_id 则为返修
//                if (!orderAppraise.get("parentId").toString().equals("-1")) {
//                    cGOrderDao.insertException(OrderException.builder()
//                            .orderCountId(id)
//                            .exceptionStatus(Constants.UserBehaviorEnum.ExceptionStatus.REPAIR.getStatus())
//                            .build());
//                }
                //该单子是否含有子工单 如果有 这个工单就是返修工单
                int isParentOrder = cGOrderDao.isParentOrder(orderId);
                if (isParentOrder > 0) {
                    cGOrderDao.insertException(OrderException.builder()
                            .orderCountId(id)
                            .exceptionStatus(Constants.UserBehaviorEnum.ExceptionStatus.REPAIR.getStatus())
                            .build());
                }
                break;
            case 4: //todo 准确率 有加号则为不准
                if (cGOrderDao.selectPartsIs(orderId) > 0) {
                    cGOrderDao.insertException(OrderException.builder()
                            .orderCountId(id)
                            .exceptionStatus(Constants.UserBehaviorEnum.ExceptionStatus.PARTSEXACT.getStatus())
                            .build());
                }
                break;
            case 5://todo 状态5-6的创建时间相减 >15 则为不准确
                if (deployTime != 0) {
                    if (entities.size() > 1 && ((entities.get(0) - entities.get(1)) > deployTime * 60)) {
                        cGOrderDao.insertException(OrderException.builder()
                                .orderCountId(id)
                                .exceptionStatus(Constants.UserBehaviorEnum.ExceptionStatus.WAREHOUSERESPONSE.getStatus())
                                .build());
                    }
                }
                break;
        }

        return true;

    }

    public String mapTotal(Integer total, Integer exceptionNum) {
        NumberFormat numberFormat = NumberFormat.getInstance();
        // 设置精确到小数点后2位
        numberFormat.setMaximumFractionDigits(2);
        String result = numberFormat.format((((float) total - (float) exceptionNum) / (float) total) * 100);
        return result + "%";
    }

    public String mapFxTotal(Integer total, Integer exceptionNum) {
        NumberFormat numberFormat = NumberFormat.getInstance();
        // 设置精确到小数点后2位
        numberFormat.setMaximumFractionDigits(2);
        String result = numberFormat.format(((float) exceptionNum / (float) total) * 100);
        return result + "%";
    }

    public Date stringConvertDate(String date) throws ParseException {
        //获得SimpleDateFormat类，我们转换为yyyy-MM-dd的时间格式
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
        //使用SimpleDateFormat的parse()方法生成Date
        Date date1 = sf.parse(date);
        //打印Date
        return date1;


    }


    public List<Map<String, Object>> OrderDetails(Map<String, Object> map
            , List<Map<String, Object>> list) {


        for (Map<String, Object> orderMap : list) {
            map.put("id", orderMap.get("parent_id"));
            Map<String, Object> hashMap = new HashMap<>();
            hashMap.put("id", orderMap.get("parent_id"));
            hashMap.put("s_id", orderMap.get("s_id").toString());

            List<String> faultInfoList = null;
            // 工单故障类型
            List<Map<String, Object>> orderFaultList = orderDao.findOrderFaultById(hashMap);

            if (orderFaultList.size() > 0) {

                faultInfoList = new ArrayList<>();

                for (Map<String, Object> faultInfoMap : orderFaultList) {

                    faultInfoList.add(faultInfoMap.get("dictionaries_name").toString());
                }
            }

            map.put("order_id", orderMap.get("id"));
            map.put("o_id", orderMap.get("o_id"));
            List<Map<String, Object>> reworkOrderMap = appDao.getReworkOrderMap(map);

            // 获取返修工单
            orderMap.put("rework_order", reworkOrderMap);

            // 获取车辆信息
            Map<String, Object> car_info = orderDao.findCarInfoById(orderMap);

            orderMap.put("car_info", car_info);
            orderMap.put("order_fault_info", faultInfoList);

            if ("2".equals(orderMap.get("order_type").toString()) || "3".equals(orderMap.get("order_type").toString())) {
                // 获取保养套餐时长
                Map<String, Object> upkeepParams = new HashMap<>(2);
                upkeepParams.put("id", orderMap.get("m_id"));
                Map<String, Object> upkeepMap = upkeepDao.getUpkeepById(upkeepParams);
                if (upkeepMap == null) {
                    orderMap.put("upkeep_time", orderMap.get("m_id"));
                } else {
                    orderMap.put("upkeep_time", upkeepMap.get("upkeep_time"));
                }
            }
            orderMap.putIfAbsent("upkeep_time", null);
        }
        return list;
    }

    public List<OrderException> countGet(List<OrderException> counts, String startTime, String endTime, String s_id) throws ParseException {
        List<OrderCount> countss = cGOrderDao.selectOrderCount(stringConvertDate(startTime)
                , stringConvertDate(endTime), s_id);
        OrderCount orderCount = new OrderCount();
        countss.forEach(item1 -> {
            if (item1.getOrderStatus() == 15) {
                orderCount.setCountSum(item1.getCountSum().longValue());
            }
        });
        Integer countSum = orderCount.getCountSum().intValue();
        counts.forEach(item -> {
            try {
                OrderException exception = cGOrderDao.selectPercentByUser(stringConvertDate(startTime), stringConvertDate(endTime)
                        , s_id, item.getUpdateUser());
                item.setPercent(mapTotal(countSum, exception.getCountSum().intValue()));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        });
        return counts;
    }

    public List<OrderException> countGettz(List<OrderException> counts, String startTime, String endTime, String s_id) throws ParseException {
        List<OrderCount> countss = cGOrderDao.selectOrderCount(stringConvertDate(startTime)
                , stringConvertDate(endTime), s_id);
        OrderCount orderCount = new OrderCount();
        countss.forEach(item1 -> {
            if (item1.getOrderStatus() == 15) {
                orderCount.setCountSum(item1.getCountSum().longValue());
            }
        });
        Integer countSum = orderCount.getCountSum().intValue();
        counts.forEach(item -> {
            try {
                OrderException exception = cGOrderDao.selectPercentByUserTz(stringConvertDate(startTime), stringConvertDate(endTime)
                        , s_id, item.getUpdateUser());
                item.setPercent(mapTotal(countSum, exception.getCountSum().intValue()));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        });
        return counts;
    }

    public List<OrderException> countGetcg(List<OrderException> counts, String startTime, String endTime, String s_id) throws ParseException {
        List<OrderCount> countss = cGOrderDao.selectOrderCount(stringConvertDate(startTime)
                , stringConvertDate(endTime), s_id);
        OrderCount orderCount = new OrderCount();
        countss.forEach(item1 -> {
            if (item1.getOrderStatus() == 15) {
                orderCount.setCountSum(item1.getCountSum().longValue());
            }
        });
        Integer countSum = orderCount.getCountSum().intValue();
        counts.forEach(item -> {
            try {
                OrderException exception = cGOrderDao.selectPercentByUserCg(stringConvertDate(startTime), stringConvertDate(endTime)
                        , s_id, item.getUpdateUser());
                item.setPercent(mapTotal(countSum, exception.getCountSum().intValue()));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        });
        return counts;
    }


    /**
     * Json方式 查询订单物流轨迹
     *
     * @param expCode 所属公司 如SF
     * @param expNo   快递编号
     * @return
     * @throws Exception
     */
    public String getOrderTracesByJson(String expCode, String expNo) throws Exception {
        String requestData = String.format("{\"OrderCode\":\"\",\"ShipperCode\":\"%s\",\"LogisticCode\":\"%s\"}", expCode, expNo);
        Map<String, String> params = this.createSystemParam(requestData, "1002");
        return sendPost(ReqURL, params);
    }

    private Map<String, String> createSystemParam(String requestData, String requestType) throws Exception {
        Map<String, String> params = new HashMap<>();
        params.put("RequestData", urlEncoder(requestData, "UTF-8"));
        params.put("EBusinessID", EBusinessID);
        params.put("RequestType", requestType);
        String dataSign = encrypt(requestData, AppKey, "UTF-8");
        params.put("DataSign", urlEncoder(dataSign, "UTF-8"));
        params.put("DataType", "2");
        return params;
    }


    private String urlEncoder(String str, String charset) throws UnsupportedEncodingException {
        return URLEncoder.encode(str, charset);
    }

    private String encrypt(String content, String keyValue, String charset) throws UnsupportedEncodingException, Exception {
        if (keyValue != null) {
            return base64(MD5(content + keyValue, charset), charset);
        }
        return base64(MD5(content, charset), charset);
    }

    private String MD5(String str, String charset) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(str.getBytes(charset));
        byte[] result = md.digest();
        StringBuffer sb = new StringBuffer(32);
        for (int i = 0; i < result.length; i++) {
            int val = result[i] & 0xff;
            if (val <= 0xf) {
                sb.append("0");
            }
            sb.append(Integer.toHexString(val));
        }
        return sb.toString().toLowerCase();
    }

    private String base64(String str, String charset) throws UnsupportedEncodingException {
        return base64Encode(str.getBytes(charset));
    }

    private static String base64Encode(byte[] data) {
        StringBuilder sb = new StringBuilder();
        int len = data.length;
        int i = 0;
        int b1, b2, b3;
        while (i < len) {
            b1 = data[i++] & 0xff;
            if (i == len) {
                sb.append(base64EncodeChars[b1 >>> 2]);
                sb.append(base64EncodeChars[(b1 & 0x3) << 4]);
                sb.append("==");
                break;
            }
            b2 = data[i++] & 0xff;
            if (i == len) {
                sb.append(base64EncodeChars[b1 >>> 2]);
                sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);
                sb.append(base64EncodeChars[(b2 & 0x0f) << 2]);
                sb.append("=");
                break;
            }
            b3 = data[i++] & 0xff;
            sb.append(base64EncodeChars[b1 >>> 2]);
            sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);
            sb.append(base64EncodeChars[((b2 & 0x0f) << 2) | ((b3 & 0xc0) >>> 6)]);
            sb.append(base64EncodeChars[b3 & 0x3f]);
        }
        return sb.toString();
    }

    private static char[] base64EncodeChars = new char[]{
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
            'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
            'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
            'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
            'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
            'w', 'x', 'y', 'z', '0', '1', '2', '3',
            '4', '5', '6', '7', '8', '9', '+', '/'};


    /**
     * Json方式 查询订单物流轨迹
     *
     * @param expCode      所属公司 如SF
     * @param expNo        快递编号
     * @param customerName 如果是顺丰则是 寄件人或者收件人手机号码后4位
     * @return
     * @throws Exception
     */
    public String getOrderTracesByJson(String expCode, String expNo, String customerName) throws Exception {
        String requestData = String.format("{\"OrderCode\":\"\",\"ShipperCode\":\"%s\",\"LogisticCode\":\"%s\",\"CustomerName\":\"%s\"}", expCode, expNo, customerName);
        Map<String, String> params = this.createSystemParam(requestData, "1002");
        return sendPost(ReqURL, params);
    }

    private String sendPost(String url, Map<String, String> params) {
        OutputStreamWriter out = null;
        BufferedReader in = null;
        StringBuilder result = new StringBuilder();
        try {
            URL realUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // POST方法
            conn.setRequestMethod("POST");
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
            conn.connect();
            // 获取URLConnection对象对应的输出流
            out = new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8);
            // 发送请求参数
            if (params != null) {
                StringBuilder param = new StringBuilder();
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    if (param.length() > 0) {
                        param.append("&");
                    }
                    param.append(entry.getKey());
                    param.append("=");
                    param.append(entry.getValue());
                }
                out.write(param.toString());
            }
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        //使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result.toString();
    }

    public String getOrderTracesTypeByJson(String expNo) throws Exception {
        String requestData = String.format("{\"LogisticCode\":\"%s\"}", expNo);
        Map<String, String> params = this.createSystemParam(requestData, "2002");
        return sendPost(ReqURL, params);
    }

    public Map<String, Object> judgeInformation(Map<String, Object> reqMap) {
        Map<String, Object> resultMap = null;
        String expNo = (String) reqMap.get("expNo");
        try {
            String information = this.getOrderTracesTypeByJson(expNo);
            resultMap = JSON.parseObject(information);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultMap;
    }



}
